﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace TextGlow.Control.Packaging
{
  public static class PackageUriHelper
  {
    public static readonly Uri PackageRootUri = new Uri("/", UriKind.Relative);
    public static readonly Uri DefaultUri = new Uri("http://defaultcontainer/");
    public const char ForwardSlashChar = '/';
    public const char BackwardSlashChar = '\\';

    public const string RelationshipPartSegmentName = "_rels";
    public const string RelationshipPartExtensionName = ".rels";



    /// <summary>
    /// Gets the name of the downloader part for the given part uri.
    /// </summary>
    /// <param name="partUri">The part URI.</param>
    /// <returns></returns>
    public static string GetDownloaderPartName(Uri partUri)
    {
      if (partUri == null)
        throw new ArgumentNullException("partUri");

      string partName = partUri.ToString();

      return partName.Substring(1);
    }

    /// <summary>
    /// Resolves the target part URI with the given source part URI.
    /// If the target part URI is not rooted, the source part URI will be used to resolve it.
    /// </summary>
    /// <param name="sourcePartUri">The source part URI.</param>
    /// <param name="targetUri">The target URI.</param>
    /// <returns></returns>
    public static Uri ResolvePartUri(Uri sourcePartUri, Uri targetUri)
    {
      Uri uri;
      if (sourcePartUri == null)
        throw new ArgumentNullException("sourcePartUri");

      if (targetUri == null)
        throw new ArgumentNullException("targetUri");

      ThrowIfAbsoluteUri(sourcePartUri);
      ThrowIfAbsoluteUri(targetUri);

      if (sourcePartUri == PackageRootUri)
        uri = new Uri(DefaultUri, targetUri);
      else
        uri = new Uri(new Uri(DefaultUri, sourcePartUri), targetUri);

      return new Uri(uri.AbsolutePath, UriKind.Relative);
    }

    private static void ThrowIfAbsoluteUri(Uri uri)
    {
      if (uri.IsAbsoluteUri)
        throw new Exception(string.Format("Cannot be an absolute URI: {0}", uri));
    }

    /// <summary>
    /// Gets the part extension from the given part uri.
    /// </summary>
    /// <param name="partUri">The part URI.</param>
    /// <returns></returns>
    public static string GetPartExtension(Uri partUri)
    {
      if (partUri == null)
        throw new ArgumentNullException("partUri");

      string extension = Path.GetExtension(partUri.OriginalString);
      if (!string.IsNullOrEmpty(extension))
        return extension.Substring(1);

      return extension;
    }

    /// <summary>
    /// Gets the part relationship URI for the given part URI.
    /// </summary>
    /// <param name="partUri">The part URI.</param>
    /// <returns></returns>
    public static Uri GetPartRelationshipUri(Uri partUri)
    {
      if (partUri == null)
        throw new ArgumentNullException("partUri");

      if (partUri == PackageRootUri)
        return PackageRelationship.ContainerRelationshipPartName;

      string partUriString = partUri.OriginalString;
      string fileName = Path.GetFileName(partUriString);
      string uriMinusFileName = partUriString.Substring(0, partUriString.Length - fileName.Length);
      string uriPlusRelationship = Path.Combine(Path.Combine(uriMinusFileName, RelationshipPartSegmentName), fileName) + RelationshipPartExtensionName;

      return new Uri(uriPlusRelationship.Replace(BackwardSlashChar, ForwardSlashChar), UriKind.Relative);
    }
  }
}